package cn.xutongxue.interview.controller;

import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import cn.xutongxue.interview.common.DeleteRequest;
import cn.xutongxue.interview.common.ResponseResult;
import cn.xutongxue.interview.constants.UserConstant;
import cn.xutongxue.interview.entity.Question;
import cn.xutongxue.interview.entity.QuestionBankMap;
import cn.xutongxue.interview.entity.dto.question.QuestionAddDto;
import cn.xutongxue.interview.entity.dto.question.QuestionQueryDto;
import cn.xutongxue.interview.entity.dto.question.QuestionRemoveBatch;
import cn.xutongxue.interview.entity.dto.question.QuestionUpdateDto;
import cn.xutongxue.interview.entity.vo.QuestionVo;
import cn.xutongxue.interview.enums.Errors;
import cn.xutongxue.interview.service.QuestionBankMapService;
import cn.xutongxue.interview.service.QuestionService;
import cn.xutongxue.interview.utils.ThrowUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;

/**
 * 题目接口
 *
 * @author Administrator
 */
@RestController
@RequestMapping("/question")
@Api(tags = "QuestionApi")
public class QuestionController {

    @Resource
    private QuestionService questionService;
    @Resource
    private QuestionBankMapService questionBankMapService;

    /**
     * 分页获取题目列表
     *
     * @param queryDto 分页查询信息
     * @return 查询结果
     */
    @ApiOperation("分页获取题目列表")
    @PostMapping("/list")
    public ResponseResult<Page<Question>> listQuestion(@RequestBody QuestionQueryDto queryDto) {
        ThrowUtils.throwIf(queryDto == null, Errors.PARAMS_ERROR);
        Page<Question> page = questionService.listQuestionByPage(queryDto);
        return ResponseResult.ok(page);
    }

    @ApiOperation("分页获取题目列表Vo")
    @PostMapping("/list/vo")
    public ResponseResult<Page<QuestionVo>> listQuestionsVo(@RequestBody QuestionQueryDto queryDto) {
        ThrowUtils.throwIf(queryDto == null, Errors.PARAMS_ERROR);
        return questionService.listQuestionVoPage(queryDto);

    }

    /**
     * 新增题目
     *
     * @param addDto 题目信息
     * @return 新增结果
     */
    @ApiOperation("添加题目")
    @PostMapping("/add")
    @SaCheckRole(UserConstant.USER_ROLE_ADMIN)
    public ResponseResult<Boolean> addQuestion(@RequestBody QuestionAddDto addDto) {
        ThrowUtils.throwIf(addDto == null, Errors.PARAMS_ERROR);
        Question question = new Question();
        BeanUtil.copyProperties(addDto, question);
        List<String> tags = addDto.getTags();
        if (tags != null) {
            question.setTags(JSONUtil.toJsonStr(tags));
        }
        long currentUserId = StpUtil.getLoginIdAsLong();
        question.setUserId(currentUserId);
        return questionService.save(question) ? ResponseResult.ok(true) : ResponseResult.fail("添加题目失败");
    }

    /**
     * 删除题目
     *
     * @param deleteRequest 待删除题目ID
     * @return 删除结果
     */
    @ApiOperation("删除题目")
    @PostMapping("/delete")
    @Transactional(rollbackFor = Exception.class)
    @SaCheckRole(UserConstant.USER_ROLE_ADMIN)
    public ResponseResult<Boolean> deleteQuestion(@RequestBody DeleteRequest deleteRequest) {
        ThrowUtils.throwIf(deleteRequest == null || deleteRequest.getId() == null, Errors.PARAMS_ERROR);
        // 删除关联表所有关联信息
        LambdaQueryWrapper<QuestionBankMap> wrapper = Wrappers.lambdaQuery(QuestionBankMap.class)
                .eq(QuestionBankMap::getQuestionId, deleteRequest.getId());
        questionBankMapService.remove(wrapper);
        // 删除题目
        return questionService.removeById(deleteRequest.getId()) ? ResponseResult.ok(true) : ResponseResult.fail("删除失败");
    }

    /**
     * 批量删除题目
     *
     * @param questionRemoveBatch 待删除题目ID列表
     * @return 删除结果
     */
    @ApiOperation("批量删除题目")
    @PostMapping("/deleteBatch")
    @SaCheckRole(UserConstant.USER_ROLE_ADMIN)
    public ResponseResult<Boolean> deleteQuestionBatch(@RequestBody QuestionRemoveBatch questionRemoveBatch) {
        ThrowUtils.throwIf(questionRemoveBatch == null, Errors.PARAMS_ERROR);
        List<Long> questionIdList = questionRemoveBatch.getQuestionIdList();
        questionService.deleteQuestionBatch(questionIdList);
        return ResponseResult.ok(true);
    }

    /**
     * 修改题目
     *
     * @param question 已修改的题目信息
     * @return 修改结果
     */
    @ApiOperation("修改题目")
    @PostMapping("/update")
    @SaCheckRole(UserConstant.USER_ROLE_ADMIN)
    public ResponseResult<Boolean> updateQuestion(@RequestBody QuestionUpdateDto questionUpdateDto) {

        ThrowUtils.throwIf(questionUpdateDto == null, Errors.PARAMS_ERROR);
        Question question = new Question();
        BeanUtil.copyProperties(questionUpdateDto, question);
        List<String> tags = questionUpdateDto.getTags();
        if (tags != null) {
            question.setTags(JSONUtil.toJsonStr(tags));
        }
        boolean result = questionService.updateById(question);
        ThrowUtils.throwIf(!result, Errors.OPERATION_ERROR);
        return  ResponseResult.ok(true);
    }

    /**
     * 根据题目ID获取题目详情
     *
     * @param id 题目id
     * @return 题目详情
     */
    @ApiOperation("获取题目详情")
    @GetMapping("/queryDetail")
    public ResponseResult<QuestionVo> queryQuestionVoById(@RequestParam Long id) {
        ThrowUtils.throwIf(id < 0, Errors.PARAMS_ERROR);
        Question question = questionService.getById(id);
        QuestionVo questionVo = QuestionVo.objToVo(question);
        return ResponseResult.ok(questionVo);
    }

    /**
     * 题目查询接口
     */
    @ApiOperation("题目查询接口")
    @PostMapping("/search/page")
    public ResponseResult<Page<Question>> searchQuestionVo(@RequestBody QuestionQueryDto queryDto) {
        ThrowUtils.throwIf(queryDto == null, Errors.PARAMS_ERROR);
        Page<Question> questionPage = questionService.searchQuestionFromEs(queryDto);
        return ResponseResult.ok(questionPage);
    }
}
